package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.bean.*;
import com.itheima.common.PageParam;
import com.itheima.dao.OrderDao;
import com.itheima.dto.DishDto;
import com.itheima.dto.OrdersDto;
import com.itheima.dto.OrdersDto;
import com.itheima.service.*;
import com.itheima.utils.BaseContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@Transactional
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private HttpSession session;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private OrderDetailService orderDetailService;


    /**
     * 提交订单
     *   1. 提交订单其实是一种添加的行为，但是它要往两张表里面添加数据： orders 和 order_detail
     *
     *   2. 先添加 orders 表、
     *      2.1 才能得到订单的id主键
     *
     *   3. 再添加order_detail 表
     *      3.1 给订单详情设置 订单id主键
     *
     * @param order
     * @return
     */
    @Override
    public int add(Orders order) {
        //1. 先添加订单表

        //1.1 设置订单号
        // 获取用户信息
        User user = (User) session.getAttribute("user");

        //获取地址信息
        AddressBook addressBook = addressBookService.getById(order.getAddressBookId());

        order.setNumber(UUID.randomUUID().toString().replace("-" , ""));
        //1.2 设置状态值 : 1 : 未付款，2： 已付款，待派送 ...
        order.setStatus(1);
        //1.3 设置用户id
        order.setUserId(user.getId());
        //1.4 设置地址id【页面提供了，不需要设置】
        //1.5 设置下单时间
        order.setOrderTime(LocalDateTime.now());
        //1.6 设置支付时间
        order.setCheckoutTime(LocalDateTime.now());
        //1.7 设置支付方式【页面提供了，不需要设置】
        //1.8 设置总金额 【页面提供了，不需要设置】
        //1.9 设置备注【页面提供了，不需要设置】
        //1.10 设置收货电话
        order.setPhone(addressBook.getPhone());
        //1.11 设置收货地址
        String address = ( addressBook.getProvinceName() != null ? addressBook.getProvinceName() : "" )
                + ( addressBook.getCityName() != null ? addressBook.getCityName() : "" )
                + ( addressBook.getDistrictName() != null ? addressBook.getDistrictName() : "" )
                + ( addressBook.getDetail() != null ? addressBook.getDetail() : "" );
        order.setAddress(address);

        //1.12 设置下单的用户名称
        order.setUserName(user.getName());
        //1.13 设置收货人名称
        order.setConsignee(addressBook.getConsignee());

        //1.1 补充数据
        //1.2 执行添加
        int row1 = orderDao.insert(order);

        //2. 再添加订单详情表 :: 详情表的数据，页面没有提供，购买的详细内容，其实就是购物车的内容。

        //2.1 获取当前用户的购物车数据
        List<ShoppingCart> cartList = shoppingCartService.list();
        int row2 = 0 ;
        if(cartList != null && cartList.size() >  0){
            //2.2 遍历每一个购物车数据
            for (ShoppingCart shoppingCart : cartList) {

                //2.3 遍历一次，构建一个订单详情对象！
                OrderDetail orderDetail = new OrderDetail();


                //2.4 把购物车的数据拷贝到订单详情对象
                BeanUtils.copyProperties(shoppingCart , orderDetail);

                //2.5 设置订单id
                orderDetail.setOrderId(order.getId());

                //2.6 添加到订单详情表
                row2 += orderDetailService.add(orderDetail);

            }
            return row2 == cartList.size() ? 1 : 0;
        }

        return row1;
    }

    @Override
    public IPage<OrdersDto> findPage(PageParam pageParam) {
        //1. 构建分页对象
        IPage<Orders> p = new Page<>(pageParam.getPage(), pageParam.getPageSize());

        //2. 构建条件对象
        LambdaQueryWrapper<Orders> lqw = new LambdaQueryWrapper<>();

        //3. 追加条件
        lqw.like(pageParam.getNumber() != null, Orders::getNumber, pageParam.getNumber());
        lqw.between((pageParam.getBeginTime() != null && pageParam.getEndTime() != null),
                Orders::getOrderTime,pageParam.getBeginTime(),pageParam.getEndTime());


        //4. 执行查询:: 得到菜品的数据，但是菜品的数据里面没有分类的数据。
        IPage<Orders> ordersIPage = orderDao.selectPage(p, lqw);

        //5. 遍历每一条菜品数据，拿着每一条菜品数据的分类id去查询分类的对象，然后回来和每一条菜品数据
        //    封装成一个DishDto
        List<OrdersDto> ordersDtoList = ordersIPage.getRecords().stream().map(orders -> {

            //1. 拿着dish的分类id去查询分类表，得到分类的对象。


            AddressBook addressBook = addressBookService.getById(orders.getAddressBookId());

            //2. 想方设法把遍历出来的dish对象和category的名称，组合成一个新的对象DishDto
            OrdersDto ordersDto = new OrdersDto();

            //2.1 设置dishDto里面的分类数据
            ordersDto.setConsignee(addressBook.getConsignee());
            ordersDto.setPhone(addressBook.getPhone());
            ordersDto.setAddress(addressBook.getDetail());

            //2.2 设置dishDto里面的菜品数据
            // BeanUtils.copyProperties： 用来拷贝数据的，拷贝同名属性 参数一：源对象，参数二：目标对象
            BeanUtils.copyProperties(orders, ordersDto);

            //2.3 设置dishDto里面的口味数据
            //2.3.1 先根据菜品的id去查询菜品口味表，得到该菜品的口味数据
            OrderDetail orderDetail = orderDetailService.getOrderDetailById(orders.getId());

            //2.3.2 添加到DishDto里面去。
            if(orderDetail != null){
                ordersDto.setAmount(orderDetail.getAmount());
            }

            //3. 返回dishDto
            return ordersDto;
        }).collect(Collectors.toList());


        //6. 构建一个新的IPage<DishDto>对象
        IPage<OrdersDto> ordersDtoIPage = new Page<>();

        //7. 设置数据，页面只需要两个数据就能够显示数据： records 和 total
        ordersDtoIPage.setTotal(ordersIPage.getTotal());
        ordersDtoIPage.setRecords(ordersDtoList);

        //8. 返回dishdtoIpage
        return ordersDtoIPage;
    }

    @Override
    public int update(Orders orders) {
        if(orders.getStatus() == 4){
            orders.setStatus(4);
        }
        if(orders.getStatus() == 3){
            orders.setStatus(3);
        }

        int row1 = orderDao.updateById(orders);

        return row1;
    }

    /**
     * 查询订单
     *
     * @param pageParam
     * @return
     */
    @Override
    public IPage<OrdersDto> page(PageParam pageParam) {
        IPage<Orders> page=new Page<>(pageParam.getPage(),pageParam.getPageSize());
        User user = (User) session.getAttribute("user");
        LambdaQueryWrapper<Orders> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Orders::getUserId,user.getId()).orderByDesc(Orders::getOrderTime);
        IPage<Orders> ordersIPage = orderDao.selectPage(page, lqw);
        List<OrdersDto> ordersDtoList = ordersIPage.getRecords().stream().map(orders -> {
            List<OrderDetail> orderDetailList = orderDetailService.findByOrderId(orders.getId());
            OrdersDto ordersDto = new OrdersDto();
            ordersDto.setOrderDetails(orderDetailList);
            BeanUtils.copyProperties(orders,ordersDto);
            return ordersDto;
        }).collect(Collectors.toList());
        IPage<OrdersDto> iPage=new Page<>();
        iPage.setTotal(ordersIPage.getTotal());
        iPage.setRecords(ordersDtoList);
        return iPage;
    }
}
